﻿using Caching;
using SmallJob.Model;
using SmallJob.Services.Code;
using SmallJob.Services.Interfaces;
using SmallShop.Services.Implements;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Web;
using System.Web.Mvc;
using System.Linq;
using SmallShop.Services.Interfaces;
using SmallShop.Services.Code;

namespace FrontEnd.Controllers
{
    public class RequestController : Controller
    {
        //
        // GET: /Request/

        private readonly IRequestService _RequestService;
        private readonly IBidRequestService _BidRequestService;
        private readonly ICategoryService _CategoryService;
        private readonly IUserService _UserService;
        private readonly IProvideCommentService _ProvideCommentService;
        private readonly IOrderService _OrderService;
        private readonly IFollowerService _FollowerService;
        private readonly IEmailFormatService _EmailFormatService;

        public RequestController(IRequestService RequestService, ICategoryService CategoryService, IUserService UserService, IProvideCommentService ProvideCommentService, IOrderService OrderService, IFollowerService FollowerService, IBidRequestService BidRequestService, IEmailFormatService EmailFormatService)
        {
            _CategoryService = CategoryService;
            _RequestService = RequestService;
            _UserService = UserService;
            _ProvideCommentService = ProvideCommentService;
            _OrderService = OrderService;
            _FollowerService = FollowerService;
            _BidRequestService = BidRequestService;
            _EmailFormatService = EmailFormatService;
        }

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Add()
        {
            if (!User.Identity.IsAuthenticated)
                return RedirectToAction("index", "home");
            int id = 0;
            var u = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
            try
            {
                id = Convert.ToInt32(RouteData.Values["id"]);
            }
            catch
            {
                id = 0;
            }
            var request = _RequestService.GetById(id);
            if (request == null)
            {
                request = new Request()
                {
                    ID = 0,
                    Price = 0,
                    Description = "",
                    EndDate = DateTime.Now,
                    CategoryID = 0,
                    Title = "",
                    Location = "",
                    AssignedUserID = 0
                };
            }
            else
            {
                if (request.AssignedUserID != u.ID)
                {
                    return RedirectToAction("index", "home");
                }
            }
            List<Category> listCate = null;
            if (MemCache.Get<List<Category>>("category") == null)
            {
                listCate = _CategoryService.GetAllAvaiable();
                MemCache.InsertCache("category", listCate);
            }
            else
            {
                listCate = MemCache.Get<List<Category>>("category");
            }
            ViewData["AllCate"] = listCate;
            return View(request);
        }

        [ValidateInput(false)]
        public ActionResult Save(int id, string description, string title, string location, int cateID, string endDate)
        {
            if (!User.Identity.IsAuthenticated)
                return RedirectToAction("index", "Home");
            var request = _RequestService.GetById(id);
            if (request == null)
                request = new Request()
                {
                    ID = 0,
                    Price = 0,
                    Description = "",
                    EndDate = DateTime.Now,
                    CategoryID = 0,
                    Title = "",
                    Location = "",
                    AssignedUserID = 0,
                    StartDate = DateTime.Now,
                    CreatedDate = DateTime.Now
                };
            request.Title = title;
            request.Location = location;
            request.CategoryID = cateID;
            request.Description = HttpUtility.HtmlEncode(description);
            request.ModifiedDate = DateTime.Now;
            request.EndDate = DateTime.ParseExact(endDate, "dd-MM-yyyy", CultureInfo.InvariantCulture);
            var u = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
            request.AssignedUserID = u.ID;
            try
            {
                request.Price = Convert.ToInt32(Request.Form["price"]) * 1000;
            }
            catch
            {
                ModelState.AddModelError("PriceInvalid", "Nhập Đúng Giá");
            }
            if (string.IsNullOrWhiteSpace(request.Title))
                ModelState.AddModelError("TitleInvalid", "Tiêu đề không được bỏ trông");
            if (string.IsNullOrWhiteSpace(request.Location))
                ModelState.AddModelError("LocationInvalid", "Địa điểm không được bỏ trông");
            if (string.IsNullOrWhiteSpace(request.Description))
                ModelState.AddModelError("DescriptionOrderInvalid", "Nội dung không được bỏ trông");

            if (ModelState.IsValid)
            {
                if (request.ID == 0)
                {
                    _RequestService.Add(request);
                    TempData["mess"] = "Thêm thành công!";
                    TempData["rID"] = request.ID;
                    request.AssignedUser = _UserService.GetById(request.AssignedUserID);
                    MemCache.InsertCache("request_" + request.ID, request);
                    var cacherequests = MemCache.Get<List<Request>>("user_request_" + request.AssignedUserID);
                    if (cacherequests != null)
                    {
                        cacherequests.Add(request);
                        cacherequests = cacherequests.OrderByDescending(r => r.ModifiedDate).ToList();
                        MemCache.InsertCache("user_request_" + request.AssignedUserID, cacherequests);

                    }
                    return RedirectToAction("Add");
                }
                else
                {
                    _RequestService.Update(request);
                    TempData["mess"] = "Sửa thành công!";
                    TempData["rID"] = request.ID;
                    request.AssignedUser = _UserService.GetById(request.AssignedUserID);
                    MemCache.InsertCache("request_" + request.ID, request);
                    var cacherequests = MemCache.Get<List<Request>>("user_request_" + request.AssignedUserID);
                    if (cacherequests != null)
                    {
                        var cache = cacherequests.SingleOrDefault(r => r.ID == request.ID);
                        cache = request;
                        cacherequests = cacherequests.OrderByDescending(r => r.ModifiedDate).ToList();
                        MemCache.InsertCache("user_request_" + request.AssignedUserID, cacherequests);
                    }
                    return new RedirectResult("/request/add/" + request.ID);
                }
            }
            List<Category> listCate = null;
            if (MemCache.Get<List<Category>>("category") == null)
            {
                listCate = _CategoryService.GetAllAvaiable();
                MemCache.InsertCache("category", listCate);
            }
            else
            {
                listCate = MemCache.Get<List<Category>>("category");
            }
            ViewData["AllCate"] = listCate;
            return View("Add", request);
        }

        public ActionResult Show(string page)
        {
            var location = Request.QueryString["paramlocation"];
            var category = Request.QueryString["paramcategory"];
            var title = Request.QueryString["paramtitle"];
            if (string.IsNullOrWhiteSpace(page))
            {
                page = "1";
            }

            ViewData["paramforpv"] = new { page = page, paramlocation = location, paramcategory = category, paramtitle = title };
            List<Category> listCate = null;
            if (MemCache.Get<List<Category>>("category") == null)
            {
                listCate = _CategoryService.GetAllAvaiable();
                MemCache.InsertCache("category", listCate);
            }
            else
            {
                listCate = MemCache.Get<List<Category>>("category");
            }
            ViewData["AllCate"] = listCate;
            return View();
        }

        public ActionResult ListRequestPV(string page, string paramlocation, string paramcategory, string paramtitle)
        {
            var model = new List<Request>();
            int indexpage = 1;
            Int32.TryParse(page, out indexpage);
            int total = 0;
            //int pagesize = Convert.ToInt32(Resources.Resource.RequestPerPage);
            int pagesize = Convert.ToInt32(Resources.Resource.RequestPerPage);

            if (string.IsNullOrWhiteSpace(paramlocation) && string.IsNullOrWhiteSpace(paramcategory) && string.IsNullOrWhiteSpace(paramtitle))
            {
                model = _RequestService.GetByPage(indexpage, pagesize, out total);
                foreach (var item in model)
                {
                    item.AssignedUser = _UserService.GetById(item.AssignedUserID);
                }
            }
            else
            {
                var categoryid = (string.IsNullOrWhiteSpace(paramcategory) ? 0 : Convert.ToInt32(paramcategory));
                model = _RequestService.GetByPageFilter(indexpage, pagesize, out total, paramlocation, categoryid, paramtitle);
                foreach (var item in model)
                {
                    item.AssignedUser = _UserService.GetById(item.AssignedUserID);
                }
            }
            if ((total % pagesize) > 0)
            {
                ViewData["total"] = (total / pagesize) + 1;
            }
            else
            {
                ViewData["total"] = total / pagesize;
            }
            ViewData["curpage"] = indexpage;

            ViewData["continueurl"] = "&paramlocation=" + paramlocation + "&paramcategory=" + paramcategory + "&paramtitle=" + paramtitle;
            return PartialView(model);
        }

        public ActionResult Details()
        {
            int id = Convert.ToInt16(RouteData.Values["id"]);
            Request request = null;
            if (MemCache.Get<Request>("request_" + id) == null)
            {
                request = _RequestService.GetById(id);
                if (request == null)
                {
                    RedirectToAction("index", "home");
                }
                request.AssignedUser = _UserService.GetById(request.AssignedUserID);
                MemCache.InsertCache("request_" + request.ID, request);
            }
            else
            {
                request = MemCache.Get<Request>("request_" + id);
            }
            var u = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
            ViewData["isOwner"] = (u == null ? false : u.ID == request.AssignedUser.ID);
            //var orders = _OrderService.GetOrderComment(request.ID);
            //foreach (var item in orders)
            //{
            //    item.Bidder = _UserService.GetById(item.BidderID);
            //}
            //ViewData["comment"] = orders;
            ViewData["isFollowwed"] = false;
            if (u != null)
            {
                if (_FollowerService.IsExist(u.ID, request.AssignedUser.ID))
                {
                    ViewData["isFollowwed"] = !_FollowerService.GetByID(u.ID, request.AssignedUser.ID).IsDeleted;
                }
            }
            var listBids = _BidRequestService.GetByRequest(request.ID);
            foreach (var item in listBids)
            {
                item.Bidder = _UserService.GetById(item.BidderID);
            }
            ViewData["lstBids"] = listBids;
            if (TempData["issuccess"] != null)
            {
                ViewData["issuccess"] = TempData["issuccess"];
                ViewData["orderid"] = TempData["orderid"];

                if (!Convert.ToBoolean(TempData["issuccess"]))
                {
                    ViewData["result"] = TempData["result"];
                }
                else
                {
                    ViewData["bidid"] = TempData["bidid"];
                    var bid = _BidRequestService.GetById(Convert.ToInt32(ViewData["bidid"]));
                    bid.Bidder = _UserService.GetById(bid.BidderID);
                    ViewData["bid"] = bid;
                }
            }
            return View(request);
        }

        [HttpPost]
        public ActionResult Delete(int id)
        {
            if (!User.Identity.IsAuthenticated) return Json(new { result = false });
            var user = UtilityService.GetLoginUser(_UserService, User);
            var request = _RequestService.GetById(id);
            if (request == null) return Json(new { result = false });
            if (user.ID != request.AssignedUserID) return Json(new { result = false });
            request.IsDeleted = true;
            request.ModifiedDate = DateTime.Now;
            _RequestService.Update(request);
            var cacherequests = MemCache.Get<List<Request>>("user_request_" + request.AssignedUserID);
            if (cacherequests != null)
            {
                var cache = cacherequests.SingleOrDefault(r => r.ID == request.ID);
                cacherequests.Remove(cache);
                cacherequests = cacherequests.OrderByDescending(r => r.ModifiedDate).ToList();
                MemCache.InsertCache("user_request_" + request.AssignedUserID, cacherequests);
            }
            return Json(new { result = true });
        }
    }
}